﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BusinessLogicLayer.Base;
using DALLayer.Providers;
using DataDefinition;
using Objects;

namespace BusinessLogicLayer.Manager
{
    public class StepManager : ManagerBase<StepDataProvider>
    {
        #region [Constructor]
        /// <summary>
        /// Initializes a new instance of the <see cref="StepManager" /> class.
        /// </summary>
        public StepManager() { } 
        #endregion

        #region [Manager base class implementations]
        /// <summary>
        /// Pass the data provider to the class
        /// </summary>
        protected override void InitializeDataProvider()
        {
            //Pass the specific data provider to the manager class
            base.DataProvider = new StepDataProvider();
        }

        #endregion

        #region [Public Methods]

        /// <summary>
        /// Gets the steps by article id
        /// </summary>
        /// <param name="articleID">article id</param>
        /// <returns>get steps user or article list</returns>
        public List<GetStepsUserOrArticle> GetStepsByArticleID(int articleID)
        {
            //The get steps user or article details
            List<GetStepsUserOrArticle> getStepsUserOrArticleDetails = null;
            try
            {
                //Get the get steps user or article details list
                getStepsUserOrArticleDetails = this.GetStepsUsersOrArticles(articleID, 0, true);
            }
            catch (Exception eX)
            {
                //log error here
            }
            //The get steps user or article list to return
            return getStepsUserOrArticleDetails;
        }
        /// <summary>
        /// Gets the steps by user id
        /// </summary>
        /// <param name="userID">user id</param>
        /// <returns>get steps user or article list</returns>
        public List<GetStepsUserOrArticle> GetStepsByUserID(int userID)
        {
            //The get steps user or article details
            List<GetStepsUserOrArticle> getStepsUserOrArticleDetails = null;
            try
            {
                //Get the get steps user or article details list
                getStepsUserOrArticleDetails = this.GetStepsUsersOrArticles(0, userID, false);
            }
            catch (Exception eX)
            {
                //log error here
            }
            //The get steps user or article list to return
            return getStepsUserOrArticleDetails;
        }
        /// <summary>
        /// Gets the steps by id
        /// </summary>
        /// <param name="stepId">the step id</param>
        /// <returns>step list</returns>
        public List<Step> GetSteps(int stepId)
        {
            //The step details
            List<Step> stepDetails = null;
            try
            {
                //Get the step details list
                stepDetails = this.GetSteps(stepId, true);
            }
            catch (Exception eX)
            {
                //log error here
            }
            //The step details list to return
            return stepDetails;
        }
        /// <summary>
        /// Update or insert an step.
        /// </summary>
        /// <param name="step">step object</param>
        /// <returns>true or false</returns>
        public bool UpdateStep(Step step)
        {
            bool success = false;
            try
            {
                //if there is an id
                if (step.StepID > 0)
                {
                    //Update the step
                    success = base.DataProvider.UpdateStep(step.StepID, step.StepName, step.StepURL, step.ArticleID, step.IsActive);
                }
                else
                {
                    //Insert an step
                    success = base.DataProvider.InsertStep(step.StepName, step.StepURL, step.ArticleID, step.IsActive);

                }
            }
            catch (Exception eX)
            {
                // log the error here
            }
            //returns true or false
            return success;

        }
        #endregion

        #region [Private Methods]
        /// <summary>
        /// The method that gets the list of steps or just one step
        /// </summary>
        /// <param name="stepId">The step id</param>
        /// <param name="selectById">The check to see if select by id or not</param>
        /// <returns>step list</returns>
        private List<Step> GetSteps(int stepId, bool selectById)
        {
            //The step details to be returned
            List<Step> stepDetails = null;
            try
            {
                //Get the data set returned from the data provider
                AutoFixDataSet dataSet = base.DataProvider.GetAllSteps(stepId, selectById);

                if (dataSet != null && dataSet.Step != null && dataSet.Step.Rows != null)
                {
                    //Set the returned filled list
                    stepDetails = FillStepObjectsByEntities(dataSet.Step);
                }
            }
            catch (Exception eX)
            {
                //log the error here, dont throw the exception
            }
            //Return the step details list
            return stepDetails;

        }

        /// <summary>
        /// Fills the step object
        /// </summary>
        /// <param name="dataTable">the data table</param>
        /// <returns>The step list</returns>
        private List<Step> FillStepObjectsByEntities(AutoFixDataSet.StepDataTable dataTable)
        {
            //The step list that contains the objects
            //Loop through the data table and create new StepObject 
            //finally select the StepObject and convert to list
            List<Step> stepDetails = (from so in
                                          (from s in dataTable.AsEnumerable<AutoFixDataSet.StepRow>()
                                           select new
                                           {
                                               StepObject = new Step()
                                               {
                                                   StepID = s.StepID,
                                                   StepName = s.StepName,
                                                   StepURL = s.StepURL,
                                                   ArticleID = s.ArticleID,
                                                   IsActive = s.IsActive
                                               }
                                           })
                                      select so.StepObject).ToList();
            //Return the filled step details list
            return stepDetails;
        }
        /// <summary>
        /// Gets steps by user or articles
        /// </summary>
        /// <param name="articleId">the article id</param>
        /// <param name="userId">the user isd</param>
        /// <param name="isArticleId">the check to see if its by article id or step id. if <value>true</value> then article id else <value>false</value> by user id</param>
        /// <returns></returns>
        private List<GetStepsUserOrArticle> GetStepsUsersOrArticles(int articleId, int userId, bool isArticleId)
        {
            //The steps user or article details to be returned
            List<GetStepsUserOrArticle> stepsUserOrArticleDetails = null;
            try
            {
                //Get the data set returned from the data provider
                AutoFixDataSet dataSet = base.DataProvider.GetStepsUsersOrArticles(isArticleId, articleId, userId);

                if (dataSet != null && dataSet.GetStepsUsersOrArticles != null && dataSet.GetStepsUsersOrArticles.Rows != null)
                {
                    //Set the returned filled list
                    stepsUserOrArticleDetails = FillStepsUserOrArticleObjectsByEntities(dataSet.GetStepsUsersOrArticles);
                }
            }
            catch (Exception eX)
            {
                //log the error here, dont throw the exception
            }
            //Return steps user or article details list
            return stepsUserOrArticleDetails;

        }
        /// <summary>
        /// Fills the get steps user or article object
        /// </summary>
        /// <param name="dataTable">the data table</param>
        /// <returns>The user article list</returns>
        private List<GetStepsUserOrArticle> FillStepsUserOrArticleObjectsByEntities(AutoFixDataSet.GetStepsUsersOrArticlesDataTable dataTable)
        {
            //The get steps user or article article list that contains the objects
            //Loop through the data table and create new GetStepsUserOrArticleObject 
            //finally select the GetStepsUserOrArticleObject and convert to list
            List<GetStepsUserOrArticle> getStepsUserOrArticleDetails = (from guoao in
                                                           (from guoa in dataTable.AsEnumerable<AutoFixDataSet.GetStepsUsersOrArticlesRow>()
                                                            select new
                                                            {
                                                                GetStepsUserOrArticleObject = new GetStepsUserOrArticle()
                                                                {
                                                                    StepName = guoa.StepName,
                                                                    StepID = guoa.StepID,
                                                                    StepURL = guoa.StepURL,
                                                                    IsPublished = guoa.IsPublished,
                                                                }
                                                            })
                                                                        select guoao.GetStepsUserOrArticleObject).ToList();
            //Return the filled get steps user or article details list
            return getStepsUserOrArticleDetails;
        }
        #endregion
    }
}
